package service

import (
	"context"
	"fmt"
	"github.com/star-find-cloud/star-chat/internal/mq"
	"github.com/star-find-cloud/star-chat/pkg/jwt"
	log "github.com/star-find-cloud/star-chat/pkg/logger"
	"github.com/star-find-cloud/star-chat/root/domain"
	"github.com/star-find-cloud/star-chat/utils"
	"time"
)

type RootSrvImpl struct {
	repo     domain.RootRepo
	cache    domain.RootCache
	producer mq.ProducerSrv
}

func NewRootSrvImpl(repo domain.RootRepo) domain.RootService {
	return &RootSrvImpl{repo: repo}
}

// TODO 实现验证码检查逻辑
func (r *RootSrvImpl) Register(ctx context.Context, root *domain.Root, VerificationCode int32) (string, error) {
	nilRoot := &domain.Root{}
	if root == nilRoot {
		return "", newSrvError(CodeInvalidObject, "root is nil", nil, "verify")
	}
	if !utils.VerifyEmail(root.Email) {
		return "", newSrvError(CodeInvalidObject, "email is invalid", nil, "verify")
	}
	if !utils.VerifyPassword(root.Password) {
		return "", newSrvError(CodeInvalidObject, "password is invalid", nil, "verify")
	}

	password, err := utils.BcryptPassword(root.Password)
	if err != nil {
		log.AppLogger.Errorf("encryption failed: %v", err)
		return "", newSrvError(CodeInternalError, "encryption failed", err, "encryption")
	}
	root.Password = password

	id, err := r.repo.Create(ctx, root)
	if err != nil {
		log.AppLogger.Errorf("register root failed: %v", err)
		return "", newSrvError(CodeInternalError, "register root failed", err, "Register")
	}

	token, err := jwt.GenerateToken(id, root.Level, "root")
	if err != nil {
		log.AppLogger.Errorf("generate token failed: %v", err)
		return "", newSrvError(CodeInternalError, "generate token failed", err, "Register")
	}

	err = r.cache.MakeTokenCache(ctx, token, id)
	if err != nil {
		log.AppLogger.Errorf("make token cache failed: %v", err)
		return "", newSrvError(CodeInternalError, "make token cache failed", err, "make cache")
	}

	event := domain.RegisterRootEvent{
		RootID:    id,
		RootEmail: root.Email,
		RootLevel: root.Level,
		CreateAt:  time.Now(),
	}

	key := fmt.Sprintf("user:id:%d", id)
	err = r.producer.SendAsyncMsg(ctx, event, "register", key)
	if err != nil {
		log.AppLogger.Errorf("send async msg failed: %v", err)
		return "", newSrvError(CodeInternalError, "send async msg failed", err, "send async msg")
	}

	return token, nil
}

func (r *RootSrvImpl) LoginByID(ctx context.Context, id int64, passwd string) (string, error) {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) LoginByName(ctx context.Context, name string, passwd string) (string, error) {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) LoginByPhone(ctx context.Context, countryCode, phone int64, passwd string) (string, error) {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) UpdateInfo(ctx context.Context, root *domain.Root) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) UpdatePassword(ctx context.Context, token string, oldPassword, newPassword string) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) UpdateIDCard(ctx context.Context, token string, idCard string) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) UpdateLevel(ctx context.Context, token string, level int32) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) UpdateLastLogin(ctx context.Context, token string) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) Enable(ctx context.Context, token string, id int64) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) Disable(ctx context.Context, token string, id int64) error {
	//TODO implement me
	panic("implement me")
}

func (r *RootSrvImpl) Delete(ctx context.Context, token string, id int64) error {
	//TODO implement me
	panic("implement me")
}
